﻿using StarsAdmin.Core.DB.Entities;
using System.Linq.Expressions;

namespace StarsAdmin.Core.BaseRepository
{
    public interface IBaseRepository<TEntity> where TEntity : BaseEntity
    {
        /// <summary>
        /// 事务处理
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        bool UseTransaction(Action action);

        /// <summary>
        /// 异步事务处理
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        Task<bool> UseTransactionAsync(Func<Task> func);

        /// <summary>
        /// 获得所有数据（包含软删除的数据）
        /// </summary>
        /// <returns></returns>
        IQueryable<TEntity> Get();

        /// <summary>
        /// 获得所有数据（不包含软删除的数据）
        /// </summary>
        /// <returns></returns>
        IQueryable<TEntity> GetAll();

        /// <summary>
        /// 根据断言表达式查询数据，默认已调用 AsNoTracking()
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="isTracking">是否取消跟踪实体</param>
        /// <returns></returns>
        IQueryable<TEntity> GetBy(Expression<Func<TEntity, bool>> predicate, bool isTracking = true);

        /// <summary>
        ///
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        IQueryable<TEntity> GetById(long id);

        /// <summary>
        /// 根据id获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<TEntity?> GetByIdAsync(long id);

        /// <summary>
        /// 根据id集合获取数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        IQueryable<TEntity> GetByIds(IEnumerable<long> ids);

        /// <summary>
        /// 根据id集合获取数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        Task<IQueryable<TEntity>> GetByIdsAsync(IEnumerable<long> ids);

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> AddAsync(TEntity entity);

        /// <summary>
        /// 添加并保存
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> AddAndSaveAsync(TEntity entity);

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<bool> AddRangeAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 批量添加并保存
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<bool> AddRangeAndSaveAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity entity);

        /// <summary>
        /// 更新并保存
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> UpdateAndSaveAsync(TEntity entity);

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<bool> UpdateRangeAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 批量更新并保存
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<bool> UpdateRangeAndSaveAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 更新某个字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<bool> AttachAsync(TEntity entity, Expression<Func<TEntity, object>> predicate);

        /// <summary>
        /// 更新某个字段并保存
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<bool> AttachAndSaveAsync(TEntity entity, Expression<Func<TEntity, object>> predicate);

        /// <summary>
        /// 批量更新某个字段
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<bool> AttachRangeAsync(IEnumerable<TEntity> entities, Expression<Func<TEntity, object>> predicate);

        /// <summary>
        /// 批量更新某个字段并保存
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<bool> AttachRangeAndSaveAsync(IEnumerable<TEntity> entities, Expression<Func<TEntity, object>> predicate);

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<bool> DeleteAsync(long id);

        /// <summary>
        /// 删除并保存
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<bool> DeleteAndSaveAsync(long id);

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        Task<bool> DeleteRangeAsync(IEnumerable<long> ids);

        /// <summary>
        /// 批量删除并保存
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        Task<bool> DeleteRangeAndSaveAsync(IEnumerable<long> ids);

        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        Task<bool> SaveChangesAsync();
    }
}